package com.alen.websocket.util;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

import java.util.ArrayList;
import java.util.List;

public class NetworkObserver {
    public static final int TYPE_WIFI = 1;
    public static final int TYPE_MOBILE = 2;
    public static final int TYPE_NOT_CONNECTED = 0;


    public static int getConnectivityStatus(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (null != activeNetwork) {
            if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
                return TYPE_WIFI;

            if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
                return TYPE_MOBILE;
        }
        return TYPE_NOT_CONNECTED;
    }

    /**
     * 判断是否有网络可用
     *
     * @param context
     * @return
     */
    public static boolean isNetAvailable(Context context) {
        NetworkInfo networkInfo = getActiveNetworkInfo(context);
        if (networkInfo != null) {
            return networkInfo.isAvailable();
        } else {
            return false;
        }
    }

    /**
     * 获取可用的网络信息
     *
     * @param context
     * @return
     */
    private static NetworkInfo getActiveNetworkInfo(Context context) {
        try {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            return cm.getActiveNetworkInfo();
        } catch (Exception e) {
            return null;
        }
    }

    static public class NetworkChangeReceiver extends BroadcastReceiver {

        private List<NetStateChangeObserver> mObservers = new ArrayList<>();
        private int mType = -1;
        private static boolean isRegister = false;

        private static class InstanceHolder {
            private static final NetworkChangeReceiver INSTANCE = new NetworkChangeReceiver();
        }

        @Override
        public void onReceive(Context context, Intent intent) {

            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
                int connectivityStatus = NetworkObserver.getConnectivityStatus(context);
                notifyObservers(connectivityStatus);
            }

        }

        public static void registerReceiver(Context context) {
            IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
            context.registerReceiver(InstanceHolder.INSTANCE, intentFilter);
            isRegister = true;
        }

        public static void unRegisterReceiver(Context context) {
            if (isRegister) {
                context.unregisterReceiver(InstanceHolder.INSTANCE);
            }
        }

        public static void addObserver(NetStateChangeObserver observer) {
            if (observer == null) {
                return;
            }
            if (!InstanceHolder.INSTANCE.mObservers.contains(observer)) {
                InstanceHolder.INSTANCE.mObservers.add(observer);
            }
        }

        public static void removeObserver(NetStateChangeObserver observer) {
            if (observer == null) {
                return;
            }
            if (InstanceHolder.INSTANCE.mObservers == null) {
                return;
            }
            InstanceHolder.INSTANCE.mObservers.remove(observer);
        }

        private void notifyObservers(int networkType) {
            if (mType == networkType) {
                return;
            }
            mType = networkType;
            if (networkType == NetworkObserver.TYPE_MOBILE) {
                for (NetStateChangeObserver observer : mObservers) {
                    observer.onMobileConnect();
                }
            } else if (networkType == NetworkObserver.TYPE_WIFI) {
                for (NetStateChangeObserver observer : mObservers) {
                    observer.onWifiConnect();
                }
            } else {
                for (NetStateChangeObserver observer : mObservers) {
                    observer.onDisconnect();
                }
            }
        }

    }

    public interface NetStateChangeObserver {

        void onDisconnect();

        void onMobileConnect();

        void onWifiConnect();
    }
}
